/* durecore_shmem.h */
/* 定义双核的共享内存, 这份代码被两个工程同时编译 */

#ifndef __DUALCORE_SHMEM_H__
#define __DUALCORE_SHMEM_H__

#include <stdint.h>
#include <stdbool.h>

/* 共享内存区为从0x2002_8000开始的32KB片内RAM空间, 为RAM2的后半段.
 * RAM0, RAM1和RAM2的前半段给core0做数据内存, 总计150KB.
 * RAM3给core1做数据内存, 总计64KB.
 * RAMX是从0x0400_0000开始的32KB, 不在常规数据内存序列, 给执行RAM代码专用.
 */
#define SHMEM_START_ADDR    0x20028000
#define SHMEM_BYTE_NUM      0x8000
#define SHMEM_WORD_NUM      (SHMEM_BYTE_NUM/4u)

/* offset = 0x0 ~ 0xf.
 * 预留给各种状态标志, 事件标志等.
 */

/* SHMEM_CORE0_STAT_REG. */
#define SHMEM_CORE0_STAT_REG_IDX   0x0  /* core0的状态标志寄存器 */
#define SHMEM_CORE0_STAT_FIFO0_READY_ACK_MASK (1u << 2u) /* 命令FIFO0准备好的应答, 举例而已. */

/* SHMEM_CORE1_STAT_REG. */
#define SHMEM_CORE1_STAT_REG_IDX   0x1  /* core1的状态标志寄存器 */
#define SHMEM_CORE1_STAT_MAIN_START_MASK     (1u << 0u) /* 进入main函数的标志. */
#define SHMEM_CORE1_STAT_HW_INIT_DONE_MASK   (1u << 1u) /* 硬件初始化完成的标志. */
#define SHMEM_CORE1_STAT_FIFO1_READY_MASK    (1u << 2u) /* 命令FIFO0准备好的标志. */


/* offset = 0x10 ~ 0x1f.
 * 预留给一个单向队列, 由core0维护捕获数据.
 */
#define SHMEM_FIFO0_LOCK_REG_IDX   0x10  /* 队列的互斥锁寄存器. */
#define SHMEM_FIFO0_WRITE_REG_IDX  0x11  /* 写指针. */
#define SHMEM_FIFO0_READ_REG_IDX   0x12  /* 读指针. */
#define SHMEM_FIFO0_COUNT_REG_IDX  0x13  /* 当前队列中的有效数据个数 */
#define SHMEM_FIFO0_BASE_REG_IDX   0x14  /* 数据开始存放的位置 */
#define SHMEM_FIFO0_OFFSET_NUM     8u    /* 0x14 - 0x1C. */


/* offset = 0x20 ~ 0x2f.
 * 预留给一个单向队列, 由core1维护捕获数据.
 */
#define SHMEM_FIFO1_LOCK_REG_IDX   0x20  /* 队列的互斥锁寄存器. */
#define SHMEM_FIFO1_WRITE_REG_IDX  0x21  /* 写指针. */
#define SHMEM_FIFO1_READ_REG_IDX   0x22  /* 读指针. */
#define SHMEM_FIFO1_COUNT_REG_IDX  0x23  /* 当前队列中的有效数据个数 */
#define SHMEM_FIFO1_BASE_REG_IDX   0x24  /* 数据开始存放的位置 */
#define SHMEM_FIFO1_OFFSET_NUM     8u    /* 0x24 - 0x2C. */


extern volatile uint32_t shmem_words[SHMEM_WORD_NUM];


/* sync events. */
void shmem_wait_core_events(uint32_t core_id, uint32_t events);
void shmem_set_core_events(uint32_t core_id, uint32_t events);

/* fifo0. core0 side, receiving from other core.
 * fifo1. coer1 side, receiving from other core.
 */
void shmem_fifo_init(uint32_t fifo_id);
uint32_t shmem_fifo_pop(uint32_t fifo_id);
bool shmem_fifo_push(uint32_t fifo_id, uint32_t dat);

#define SHMEM_FIFO1_CMD_VALID_CODE (0x01000000)
#define SHMEM_FIFO1_CMD_VALUE(x)  ( (x) | SHMEM_FIFO1_CMD_VALID_CODE )
typedef enum
{
    shmem_fifo1_cmd_led_ctrl = SHMEM_FIFO1_CMD_VALUE(0), /* 控制亮灯, 跟随1个参数, 1:开灯, 0:关灯. */
    shmem_fifo1_cmd_lcd_new_passcode = SHMEM_FIFO1_CMD_VALUE(1), /* 跟1个参数. */
    shmem_fifo1_cmd_lcd_show_passcode = SHMEM_FIFO1_CMD_VALUE(2),/* 跟2个参数. */
    shmem_fifo1_cmd_lcd_show_match = SHMEM_FIFO1_CMD_VALUE(3),/* 跟1个参数. */
    shmem_fifo1_cmd_lcd_show_nn_time = SHMEM_FIFO1_CMD_VALUE(4),/* 跟1个参数. */
} shmem_cmd_t;

typedef struct
{
    shmem_cmd_t cmd;
    uint32_t param[4];
    bool is_full;
} shmem_cmd_msg_t;

#endif /* __DUALCORE_SHMEM_H__ */

